package com.hikvision.rfiddemo;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import com.hikvision.HikUhfSdkManager;
import com.hikvision.bean.FilterData;
import com.hikvision.bean.Gen2Entity;
import com.hikvision.bean.GenData;
import com.hikvision.bean.InventoryModeEntity;
import com.hikvision.bean.UHFTAGInfo;
import com.hikvision.callback.ServiceConnectCallback;

import com.hikvision.constant.InventoryMode;
import com.hikvision.constant.LockBank;

import com.hikvision.constant.LockMode;
import com.hikvision.constant.UHFBank;
import com.hikvision.uhfservice.IAdilCallback;
import com.hikvision.utils.JsonUtil;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * 演示如何使用HikUhfSdkManager
 * <p>
 * 接入说明：
 * 1. 获取权柄：uhfSdk = HikUhfSdkManager.getInstance(mContext);
 * 2. 初始化：uhfSdk.init(mConnectCallback);
 * 3. 正常使用uhf功能
 * 4. 结束调用 uhfSdk.unInit();
 * 循环盘点使用说明：
 * 1. 设置数据回调：uhfSdk.registerCallback(callback);
 * 2. 开启循环盘点：uhfSdk.startInventoryTag();
 * 3. 使用完毕时，停止循环盘点：uhfSdk.stopInventoryTag();
 */
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();
    protected List<String> mList;

    private HomeAdapter mHomeAdaper;
    private RecyclerView mRecyclerView;
    private StaggeredHomeAdapter mStaggeredHomeAdapter;
    private HikUhfSdkManager uhfSdk;

    private Context mContext;

    private boolean isConnected = false;
    private Handler handler;
    private TextView content;
    private ScrollView scrollView;


    private int power = 25;
    private int filterBank = UHFBank.Bank_EPC;
    private int filterAddress = 32;
    private String filterData = "AAAA";
    private boolean isFilter = true;





    private int inventoryMode = InventoryMode.EPC_TID_USER;
    private int inventoryMode_User_Address = 0;
    private int inventoryMode_User_Length = 1;

    private List<Integer> lockBank = new ArrayList<>(Arrays.asList(LockBank.LockBank_EPC, LockBank.LockBank_TID));

    private int lockMode = LockMode.LockMode_LOCK;

    private String lockCode;//锁定码

    private String newAcckPwd = "11111111";//修改后的访问密码密码
    private String accPwd = "00000000";//访问密码
    private String killPwd = "11111111";//访问密码

    private int handleButtonMapping = HandleButtonMapping.UHF;

    private boolean beep = true;
    private boolean save = true;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        mList = new ArrayList<String>();
        initData();
        initView();
        handler = new Handler();
        uhfSdk = HikUhfSdkManager.getInstance(mContext);
    }


    private void initView() {
        mRecyclerView = (RecyclerView) this.findViewById(R.id.recycler);
        //设置GridView
        setGridView();
        content = findViewById(R.id.content);
        scrollView = findViewById(R.id.scrollView);
    }


    @Override
    protected void onResume() {
        super.onResume();
        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                uhfSdk.registerCallback(callback);
            }
        });
    }


    @Override
    protected void onPause() {
        super.onPause();
        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                uhfSdk.unregisterCallback();
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                uhfSdk.free();
            }
        });
    }

    public void setGridView() {
        mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,
                StaggeredGridLayoutManager.VERTICAL));
        mRecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mHomeAdaper = new HomeAdapter(this, mList);
        setLister();
        mRecyclerView.setAdapter(mHomeAdaper);
    }

    private ServiceConnectCallback mConnectCallback = new ServiceConnectCallback() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//            Toast.makeText(mContext, "Connect", Toast.LENGTH_SHORT).show();
            // TODO 连接UHF服务成功
            toast("Connect");
            isConnected = true;

            ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                @Override
                public void run() {
                    uhfSdk.registerCallback(callback);
                }
            });
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
//            Toast.makeText(mContext, "disConnect", Toast.LENGTH_SHORT).show();
            // TODO 连接UHF服务失败
            toast("disConnect");
            isConnected = false;
        }
    };

    private IAdilCallback callback = new IAdilCallback.Stub() {

        @Override
        public void message(int i) throws RemoteException {
            // TODO 升级进度回调
            Log.d(TAG, "message: i = " + i);
            if (i == 100){
                toast("导出成功");
            }
        }

        @Override
        public void onCommandStatus(int i) throws RemoteException {
            // TODO 接口调用失败状态码回调
//            toast("onCommandStatus : " + i);
            Log.d(TAG, "onCommandStatus: ");
        }


    };

    private void initData() {
        mList.add(getString(R.string.init));
        mList.add(getString(R.string.deInit));
        mList.add(getString(R.string.inventory_single_tag));
        mList.add(getString(R.string.version));
        mList.add(getString(R.string.callback));
        mList.add(getString(R.string.de_callback));
        mList.add(getString(R.string.start_inventory));
        mList.add(getString(R.string.stop_inventory));
        mList.add(getString(R.string.is_inventory));
        mList.add(getString(R.string.get_power));
        mList.add(getString(R.string.set_power));
        mList.add(getString(R.string.set_filter));
        mList.add(getString(R.string.get_filter));
        mList.add(getString(R.string.set_frequency_mode));
        mList.add(getString(R.string.get_frequency_mode));
        mList.add(getString(R.string.set_protocol));
        mList.add(getString(R.string.get_protocol));
        mList.add(getString(R.string.set_gen2));
        mList.add(getString(R.string.get_gen2));
        mList.add(getString(R.string.set_inventory_mode_entity));
        mList.add(getString(R.string.get_inventory_mode_entity));
        mList.add(getString(R.string.generate_lock_code));
        mList.add(getString(R.string.lock_mem));
        mList.add(getString(R.string.kill_tag));
        mList.add(getString(R.string.get_temperature));
        mList.add(getString(R.string.set_beep));
        mList.add(getString(R.string.get_beep));
        mList.add(getString(R.string.set_save_data));
        mList.add(getString(R.string.get_save_data));
        mList.add(getString(R.string.read_data));
        mList.add(getString(R.string.write_data));
        mList.add(getString(R.string.set_handle_trigger_mode));
        mList.add(getString(R.string.get_handle_trigger_mode));
        mList.add(getString(R.string.export_data));


    }

    private void setLister() {
        mHomeAdaper.setOnItemClickListener(new HomeAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                if (!isConnected && !mList.get(position).equals("init")) {
//                    Toast.makeText(mContext, "disConnect", Toast.LENGTH_SHORT).show();
                    toast("disConnect");
                }
                switch (mList.get(position)) {
                    case "init":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                uhfSdk.init(mConnectCallback);
                            }
                        });
                        break;
                    case "deInit":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean free = uhfSdk.free();
                                toast("free :" + free);
                            }
                        });
                        break;
                    case "单步盘点":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                UHFTAGInfo uhftagInfo = uhfSdk.inventorySingleTag();
                                scroll2Bottom(uhftagInfo.toString());
                            }
                        });
                        break;
                    case "版本信息":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                Map<String, String> uhfVersion = uhfSdk.getUhfVersion();
                                scroll2Bottom(uhfVersion.toString());
                            }
                        });
                        break;
                    case "设置回调":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.registerCallback(callback);
                                toast("设置回调 : " + ret);
                            }
                        });
                        break;
                    case "取消回调":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.registerCallback(callback);
                                toast("取消回调 : " + ret);
                            }
                        });
                        break;
                    case "开始循环盘点":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int ret = uhfSdk.startInventoryTag();
                                toast("开始循环盘点 : " + ret);
                            }
                        });
                        break;
                    case "停止循环盘点":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int ret = uhfSdk.stopInventory();
                                toast("停止循环盘点 : " + ret);
                            }
                        });
                        break;
                    case "是否在循环盘点":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.isInventoryLoop();
                                toast("是否在循环盘点 : " + ret);
                            }
                        });
                        break;
                    case "获取功率":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int power = uhfSdk.getPower();
                                toast("获取功率 : " + power);
                            }
                        });
                        break;
                    case "设置功率":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int ret = uhfSdk.setPower(power);
                                toast("设置功率 : " + ret + " power = " + power);
                            }
                        });
                        break;
                    case "设置过滤":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.setFilterData(new FilterData(filterBank, filterAddress, filterData, isFilter));
                                toast("设置过滤 : " + ret);
                            }
                        });
                        break;
                    case "获取过滤":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                FilterData data = uhfSdk.getFilterData();
                                toast("获取过滤 : " + data.toString());
                            }
                        });
                        break;

                    case "获取频率":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int frequencyMode = uhfSdk.getFrequencyMode();
                                toast("获取频率: " + frequencyMode);
                            }
                        });
                        break;

                    case "获取协议":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int ret = uhfSdk.getProtocol();
                                toast("获取协议 : " + ret);
                            }
                        });
                        break;
                    case "获取GEN2":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                Gen2Entity gen2 = uhfSdk.getGen2();
                                Log.d(TAG, "run: gen2 = " + gen2.toString());
                                scroll2Bottom(gen2.toString());
                            }
                        });
                        break;
                    case "设置盘点模式":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                InventoryModeEntity modeEntity = new InventoryModeEntity();
                                modeEntity.setMode(inventoryMode);
                                modeEntity.setUserLength(inventoryMode_User_Length);
                                modeEntity.setUserOffset(inventoryMode_User_Address);
                                boolean ret = uhfSdk.setInventoryModeEntity(modeEntity);
                                toast("设置盘点模式:" + ret);
                            }
                        });
                        break;
                    case "获取盘点模式":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                InventoryModeEntity entity = uhfSdk.getInventoryModeEntity();
                                Log.d(TAG, "run: entity = " + entity);
                                scroll2Bottom(entity.toString());
                            }
                        });
                        break;
                    case "生成锁定码":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                lockCode = uhfSdk.generateLockCode(lockBank, lockMode);
                                scroll2Bottom("锁定码:" + lockCode);
                            }
                        });
                        break;
                    case "锁定":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.lockMem(newAcckPwd,UHFBank.Bank_EPC, 32, 16, "AAAA", lockCode);//注意锁定密码不能为默认密码，所以锁定操作前需要修改访问密码为非默认密码
                                toast("锁定 : " + ret);
                            }
                        });
                        break;
                    case "销毁":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.killTag(killPwd, UHFBank.Bank_EPC, 32, 16, "AAAA");//注意销毁密码不能为默认密码，所以销毁操作前需要修销毁问密码为非默认密码
                                toast("销毁 : " + ret);
                            }
                        });
                        break;
                    case "获取温度":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int temperature = uhfSdk.getTemperature();
                                toast("获取温度 : " + temperature);
                            }
                        });
                        break;
                    case "设置按键触发模式":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.setHandlerTriggerMode(handleButtonMapping);
                                toast("设置按键触发模式 : " + ret);
                            }
                        });
                        break;
                    case "获取按键触发模式":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                int mapping = uhfSdk.getHandlerTriggerMode();
                                toast("获取按键触发模式 : " + mapping);
                            }
                        });
                        break;
                    case "设置蜂鸣器":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.setBeep(beep);
                                toast("设置蜂鸣器 : " + ret);
                            }
                        });
                        break;
                    case "获取蜂鸣器":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.getBeep();
                                toast("获取蜂鸣器 : " + ret);
                            }
                        });
                        break;
                    case "设置保存":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.setSaveData(save);
                                toast("设置保存 : ret = " + ret);
                            }
                        });
                        break;
                    case "获取保存":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean saveData = uhfSdk.isSaveData();
                                toast("获取保存 : " + saveData);
                            }
                        });
                        break;
                    case "读取数据":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                String data = uhfSdk.readData(new GenData(accPwd, UHFBank.Bank_EPC, 0, 8));//读取RESERVED 的前16个数据
                                scroll2Bottom("读取数据 data = " + data);
                            }
                        });
                        break;
                    case "写入数据":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                boolean ret = uhfSdk.writeData(new GenData(accPwd, UHFBank.Bank_RESERVED, 0, killPwd.length() / 4, killPwd));
                                toast("写入数据 : " + ret);
                            }
                        });
                        break;
                    case "导出数据":
                        ThreadPoolManager.getSingleThreadExecutor().execute(new Runnable() {
                            @Override
                            public void run() {
                                @SuppressLint("SdCardPath")
                                String filePath = "/sdcard/uhfdata";
                                File file = new File(filePath);
                                if (!file.exists()) {
                                    Log.d(TAG, "handleMessage: ");
                                    file.mkdirs();
                                }
                                Date date = new Date();
                                @SuppressLint("SimpleDateFormat")
                                SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmss");//格式化为一个固定格式的字符串
                                String format = sdf.format(date);
                                Log.d(TAG, "onClick: format = " + format);
                                String excelFileName = "/outdata_" + format + ".xlsx";
                                filePath = filePath + excelFileName;
                                uhfSdk.exportData(0,System.currentTimeMillis(),filePath);
                            }
                        });
                        break;
                    default:
                        toast("暂未添加测试");


                }
            }

            @Override
            public void onItemLongClick(View view, final int position) {

            }
        });
    }


    private void toast(String message) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void scroll2Bottom(String value) {

        handler.post(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                if (scrollView == null || content == null) {
                    return;
                }
                content.append(value + "\n");
                // 内层高度超过外层
                int offset = content.getMeasuredHeight()
                        - scrollView.getMeasuredHeight();
                if (offset < 0) {
                    offset = 0;
                }
                scrollView.scrollTo(0, offset);
            }
        });

    }
}